import copy
import datetime
import os
import re
import time
from functools import lru_cache

import xmltodict

from app.config import source_dbs_path, decrypt_dbs_path, key, message_temp_path
from app.db.db_query import get_msg, get_user_info_by_wxid, get_msg_db
from app.db.encrypt_db import EncryptDb
from app.utils import get_file_md5


@lru_cache(None)
def get_user_chat_file(user):
    # 获取微信聊天文件（静态资源）
    data = {}
    for mtype in ["Audio", "Image", "Video"]:
        data[mtype] = {}
        for root, dirs, files in os.walk(message_temp_path + user + "/" + mtype):
            for f in files:
                chat_file = os.path.join(root, f)
                data[mtype][get_file_md5(chat_file)] = chat_file

    return data


def get_chat_msg_by_flag(flag, page=1, order_by="ASC"):
    # 获取个人或群聊 聊天记录
    file_list = get_user_chat_file(flag["m_nsUsrName_md5"])
    file_list = copy.deepcopy(file_list)
    data = get_msg(flag["m_nsUsrName"], page, order_by)
    for line in data:
        line["file_path"] = ""
        line["user_name"] = ""
        line["head_url"] = ""

        if not line["msgSource"]:
            try:
                line["msgContent"] = xmltodict.parse(line["msgContent"])
            except:
                pass

        elif line["messageType"] in [49, 34, 10000, 3, 34, 43, 47]:
            line["msgContent"] = line["msgContent"].lstrip("\n")
            try:
                line["msgContent"] = xmltodict.parse(line["msgContent"])
            except:
                pass

            # 媒体文件
            if line["messageType"] == 3:
                md5 = line["msgContent"]["msg"]["img"].get("@md5", "")
                line["file_path"] = file_list["Image"].pop(md5, None)

            elif line["messageType"] == 34:
                md5 = line["msgContent"]["msg"]["voicemsg"].get("@md5", "")
                line["file_path"] = file_list["Audio"].pop(md5, None)

            elif line["messageType"] == 43:
                md5 = line["msgContent"]["msg"]["videomsg"].get("@md5", "")
                line["file_path"] = file_list["Video"].pop(md5, None)


            elif line["messageType"] == 47:
                cdnurl = line["msgContent"]["msg"]["emoji"].get("@cdnurl", "")
                line["emoji_url"] = cdnurl

        user_info = get_user_info_by_wxid(line["sender_wxid"])
        if user_info:
            line["user_name"] = user_info[5] or user_info[2]
            line["head_url"] = user_info[14]

        line["msgCreateTime"] = time.strftime("%Y-%m-%d %H:%M", time.localtime(line["msgCreateTime"]))

    # data = _update_msg_file_path(file_list, data)

    return data


def _update_msg_file_path(file_list, data):
    # 匹配图片、视频、语音

    new_file_list = {}
    for mtype in file_list:
        new_file_list[mtype] = {}
        if mtype != "Image":
            continue

        for line, file_path in file_list[mtype].items():
            msg_date = time.strftime("%Y-%m-%d", time.localtime(int(os.stat(file_path).st_mtime)))
            key = "{}:{}".format(msg_date, os.path.getsize(file_path))
            new_file_list[mtype][key] = file_path
    # print("-" * 100)
    for line in data:
        if not line["file_path"]:
            if line["messageType"] == 3:
                length = re.findall(' length="(\d+?)"', line["msgContent"])
                if length:
                    msg_date = line["msgCreateTime"].split(" ")[0]
                    msg_date = datetime.datetime.strptime(msg_date, '%Y-%m-%d')
                    key = "{}:{}".format(msg_date.strftime('%Y-%m-%d'), length[0])
                    # msg_date += datetime.timedelta(days=1)
                    # key = "{}:{}".format(msg_date.strftime('%Y-%m-%d'), length[0])
                    # print(key)

                    line["file_path"] = new_file_list["Image"].pop(key, None)
                    # print(line["mesSvrID"], key, line["file_path"])
                else:
                    # TODO
                    pass

    return data


def update_msg_text(name_md5, mesLocalID, msgContent):
    # 更新数据表信息
    decrypt_db, table_name, db_file_path = get_msg_db(name_md5)
    encrypt_db = EncryptDb(source_dbs_path, db_file_path, decrypt_dbs_path, key)
    sql = "update {} set msgContent='{}' where mesLocalID='{}';".format(table_name, msgContent, mesLocalID)
    decrypt_db.exec_update_sql(sql)
    encrypt_db.exec_update_sql(sql)
